/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License"),
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup TeeTrusted
 * @{
 *
 * @brief TEE（Trusted Excution Environment）可信执行环境API。
 *
 * 提供安全能力API，例如可信存储、加解密及可信时间等，用于可信应用程序开发。
 *
 * @since 20
 */

/**
 * @file tee_mem_mgmt_api.h
 *
 * @brief 提供内存管理相关的API。
 *
 * @library NA
 * @kit TEEKit
 * @include <TEEKit/tee_mem_mgmt_api.h>
 * @syscap SystemCapability.Tee.TeeClient
 * @since 20
 */

#ifndef TEE_MEM_MGMT_API_H
#define TEE_MEM_MGMT_API_H

#include "tee_defines.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef ZERO_SIZE_PTR
/**
 * @brief 表示零大小指针。
 *
 * @since 20
 */
#define ZERO_SIZE_PTR       ((void *)16)
/**
 * @brief 检查指针是否为零大小或NULL。
 *
 * @since 20
 */
#define zero_or_null_ptr(x) ((unsigned long)(x) <= (unsigned long)ZERO_SIZE_PTR)
#endif

/**
 * @brief 定义内存分配的提示枚举值。
 *
 * @since 20
 */
enum MALLOC_HINT {
    /** 未初始化的缓冲区。 */
    ZERO           = 0,
    /** 非零初始化的缓冲区。 */
    NOT_ZERO       = 1,
    /** 4字节对齐的缓冲区。 */
    ALIGN_004      = 0x80000002,
    /** 8字节对齐的缓冲区。 */
    ALIGN_008      = 0x80000003,
    /** 16字节对齐的缓冲区。 */
    ALIGN_016      = 0x80000004,
    /** 32字节对齐的缓冲区。 */
    ALIGN_032      = 0x80000005,
    /** 64字节对齐的缓冲区。 */
    ALIGN_064      = 0x80000006,
    /** 128字节对齐的缓冲区。 */
    ALIGN_128      = 0x80000007,
    /** 256字节对齐的缓冲区。 */
    ALIGN_256      = 0x80000008,
    /** 4字节对齐并初始化为零的缓冲区。 */
    ALIGN_004_ZERO = 0x80000012,
    /** 8字节对齐并初始化为零的缓冲区。 */
    ALIGN_008_ZERO = 0x80000013,
    /** 16字节对齐并初始化为零的缓冲区。 */
    ALIGN_016_ZERO = 0x80000014,
    /** 32字节对齐并初始化为零的缓冲区。 */
    ALIGN_032_ZERO = 0x80000015,
    /** 64字节对齐并初始化为零的缓冲区。 */
    ALIGN_064_ZERO = 0x80000016,
    /** 128字节对齐并初始化为零的缓冲区。 */
    ALIGN_128_ZERO = 0x80000017,
    /** 256字节对齐并初始化为零的缓冲区。 */
    ALIGN_256_ZERO = 0x80000018,
};

/**
 * @brief 分配的内存填充为零。
 *
 * @since 20
 */
#define TEE_MALLOC_FILL_ZERO 0x00000000

/**
 * @brief 分配的内存不进行填充。
 *
 * @since 20
 */
#define TEE_MALLOC_NO_FILL   0x00000001

/**
 * @brief 分配的内存不可共享。
 *
 * @since 20
 */
#define TEE_MALLOC_NO_SHARE  0x00000002

/**
 * @brief 允许内存的读权限。
 *
 * @since 20
 */
#define TEE_MEMORY_ACCESS_READ 0x00000001

/**
 * @brief 允许内存的写权限。
 *
 * @since 20
 */
#define TEE_MEMORY_ACCESS_WRITE 0x00000002

/**
 * @brief 允许内存由任意所有者访问。
 *
 * @since 20
 */
#define TEE_MEMORY_ACCESS_ANY_OWNER 0x00000004

/**
 * @brief 将指定值x填充到缓冲区的前size个字节中。
 *
 * @param buffer 指向要填充的缓冲区的指针。
 * @param x 要填充的值。
 * @param size 要填充的字节数。
 *
 * @since 20
 */
void TEE_MemFill(void *buffer, uint8_t x, size_t size);

/**
 * @brief 复制指定数量的字节。
 *
 * @param dest 指向存储复制后字节的缓冲区的指针。
 * @param src 指向要复制的字节所在的缓冲区的指针。
 * @param size 要复制的字节数。
 *
 * @since 20
 */
void TEE_MemMove(void *dest, const void *src, size_t size);

/**
 * @brief 为对象分配指定大小的内存空间。
 *
 * @param size 要分配的内存大小。
 * @param hint 提供给分配器的提示。值为0表示返回的内存块已填充为 "\0"。
 *
 * @return 成功时，返回指向新分配内存空间的指针。\n
 *         失败时，返回NULL指针。
 *
 * @since 20
 */
void *TEE_Malloc(size_t size, uint32_t hint);

/**
 * @brief 释放由TEE_Malloc分配的内存。
 *
 * 如果缓冲区指针为NULL，TEE_Free不执行任何操作。\n
 * 要释放的缓冲区必须由TEE_Malloc或TEE_Realloc分配，且不能重复释放，
 * 否则可能导致意外结果。
 *
 * @param buffer 指向要释放的内存的指针。
 *
 * @since 20
 */
void TEE_Free(void *buffer);

/**
 * @brief 重新分配内存。
 *
 * 如果new_size大于原有大小，原内存的内容保持不变，超出部分包含未指定的内容。\n
 * 如果新内存对象的大小需要移动对象，则会释放之前的内存空间。\n
 * 如果无法分配空间，原内存对象仍保持分配状态，且该函数返回NULL指针。\n
 * 如果缓冲区指针为NULL，此函数等效于TEE_Malloc。
 *
 * @param buffer 指向要重新分配内存的指针。
 * @param new_size 指定所需的新内存大小。
 *
 * @return 成功时，返回指向已分配内存的指针。\n
 *         失败时，返回NULL指针。
 * @since 20
 */
void *TEE_Realloc(void *buffer, size_t new_size);

/**
 * @brief 从起始位置比较内存内容。
 *
 * @param buffer1 指向第一个缓冲区的指针。
 * @param buffer2 指向第二个缓冲区的指针。
 * @param size 指定要比较的字节数。
 *
 * @return 返回-1表示buffer1<buffer2。\n
 *         返回0表示buffer1==buffer2。\n
 *         返回1表示buffer1>buffer2。
 * @since 20
 */
int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, size_t size);

/**
 * @brief 检查当前TA是否具有访问指定缓冲区的权限。
 *
 * @param accessFlags 指定要检查的访问权限。
 * @param buffer 指向目标缓冲区的指针。
 * @param size 指定要检查的缓冲区大小。
 *
 * @return TEE_SUCCESS：TA具有所请求的权限。\n
 *         TEE_ERROR_ACCESS_DENIED：无权限。
 * @since 20
 */
TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, const void *buffer, size_t size);

/**
 * @brief 设置TA实例数据指针。
 *
 * @param instanceData 指向全局TA实例数据的指针。
 *
 * @since 20
 */
void TEE_SetInstanceData(void *instanceData);

/**
 * @brief 获取由TA使用TEE_SetInstanceData设置的实例数据指针。
 *
 * @return 返回由TEE_SetInstanceData设置的实例数据指针。\n
 *         如果未设置实例数据指针，则返回NULL。
 * @since 20
 */
void *TEE_GetInstanceData(void);

#ifdef __cplusplus
}
#endif

#endif
/** @} */